def myfunc(s, vt, o):
    return "".join((o, vt, s))


print(myfunc("我", "打了", "小甲鱼"))  # 小甲鱼打了我
print(myfunc("小甲鱼", "打了", "我"))  # 我打了小甲鱼

# 关键字参数，传进去的顺序无所谓
print(myfunc(o='我', vt='打了', s='小甲鱼'))  # 我打了小甲鱼

# 那么，能不能同时使用关键字参数跟位置参数呢？
# print(myfunc(o='我', '清蒸', '小甲鱼'))  # SyntaxError: positional argument follows keyword argument

# 要求：位置参数必须在关键字参数前面
print(myfunc('清蒸', '小甲鱼', o='我'))  # 我小甲鱼清蒸


# 默认参数
# 如果要使用默认参数，要放在最后
def myfunc2(s, vt, o='小甲鱼'):
    return "".join((o, vt, s))


print(myfunc2('香蕉', '吃'))  # 小甲鱼吃香蕉
print(myfunc2('香蕉', '吃', "你"))  # 你吃香蕉

# 默认参数
# non-default parameter follows default parameter
# 如果要使用默认参数，要放在最后
# def myfunc3(s="苹果", vt, o='小甲鱼'):
#     return "".join((o, vt, s))

print(help(abs))

# abs(x, /)
#     Return the absolute value of the argument.

print(help(sum))

# sum(iterable, /, start=0)
#     Return the sum of a 'start' value (default: 0) plus an iterable of numbers

# 如上面，abs 跟 sum 函数 中都有 /,表示什么意思呢？
# 表示在 / 前面的参数必须传递位置参数，而不能是关键字参数

print(abs(-1.5))
# -1.5 只能通过位置参数传递，而不能使用关键字参数传递
# print(abs(x=-1.5)) # TypeError: abs() takes no keyword arguments


print(sum([1, 2, 3], 0))  # 6

# / 后面的参数可以通过关键字 start 的方式传递，但是 start 前面参数不能通过关键字的方式传递
print(sum([1, 2, 3], start=1))  # 7


# 自定义带 / 的函数

# 在 / 前面的参数必须传递位置参数，而不能是关键字参数
def abc(a, /, b, c):
    print(a, b, c)


abc(1, 2, 3)  # 1 2 3
abc(1, c=3, b=2)  # 1 2 3


# 如果这样写就不行，因为参数a在/前面，只能通过位置传递
# abc(a=1, c=3, b=2)  # 1 2 3


# * 表示：它的左侧既可以是位置参数，也可以是关键字参数，但是她的右侧必须是关键字参数
def abc_2(a, *, b, c):
    print(a, b, c)


# * 表示：它的左侧既可以是位置参数，也可以是关键字参数，但是她的右侧必须是关键字参数
# print(abc_2(1, 2, 3))  # TypeError: abc_2() takes 1 positional argument but 3 were given
# abc_2(a=1, 2, 3)
abc_2(1, b=2, c=3)  # 1 2 3
abc_2(a=1, b=2, c=3)  # 1 2 3
